﻿using Crgd.UAuthServer.Application;
using Furion;
using Furion.DatabaseAccessor;
using Furion.Extras.Admin.NET;
using Furion.Extras.Admin.NET.Entity;
using Furion.Extras.Admin.NET.Service;
using Microsoft.AspNetCore.Identity;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Crgd.UAuthServer
{
    public static class QueryableFilterExtensions
    {
        /// <summary>
        /// 按租户ID过滤
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryable"></param>
        /// <param name="tenantId">租户ID</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public static IQueryable<T> OnlyTenant<T>(this IQueryable<T> queryable, long tenantId) where T : DEntityTenant
        {
            return queryable.Where(p => p.TenantId == tenantId);
        }

        /// <summary>
        /// 使用当前租户ID过滤
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryable"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public static IQueryable<T> OnlyTenant<T>(this IQueryable<T> queryable) where T : DEntityTenant
        {
            if (!App.User.Identity.IsAuthenticated)
            {
                throw new InvalidOperationException("仅可在已登录的用户请求上下文中使用");
            }
            var tenantId = Convert.ToInt64(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value);
            return OnlyTenant(queryable, tenantId);
        }

        /// <summary>
        /// 根据权限过滤当前用户下的数据
        /// </summary>
        /// <returns></returns>
        public static IQueryable<T> OnlyUser<T>(this IQueryable<T> queryable) where T : IDataPermissions
        {
            if (!App.User.Identity.IsAuthenticated)
            {
                throw new InvalidOperationException("仅可在已登录的用户请求上下文中使用");
            }
            var userId = Convert.ToInt64(App.User.FindFirst(ClaimConst.CLAINM_USERID).Value);
            var tenantId = Convert.ToInt64(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value);

            var userService = App.GetRequiredService<IAppSysUserService>();
            var scopedIds = userService.GetUserDataScopeIdList().Result;
            return queryable.Where(p =>
                (
                    p.CreatedUserId == userId ||
                    (p.CreatedUserOrgId.HasValue && scopedIds.Contains(p.CreatedUserOrgId.Value))
                ));
        }

        /// <summary>
        /// 限定仅查询未删除的
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queryable"></param>
        /// <returns></returns>
        public static IQueryable<T> OnlyNotDeleted<T>(this IQueryable<T> queryable) where T : DEntityTenant
        {
            return queryable.Where(p => !p.IsDeleted);
        }

        ///// <summary>
        ///// 包含已删除的数据
        ///// </summary>
        ///// <typeparam name="T"></typeparam>
        ///// <param name="queryable"></param>
        ///// <returns></returns>
        //public static IQueryable<T> IncludeDeleted<T>(this IQueryable<T> queryable) where T : DEntityBase
        //{
        //    return queryable.IgnoreQueryFilters();
        //}

        //public static IQueryable<T> IncludeAllTenant<T>(this IQueryable<T> queryable) where T : DEntityTenant
        //{
        //    return queryable.IgnoreQueryFilters().Where(p => p.IsDeleted == false);
        //}
    }
}
